"""
AI Web MCP工具数据模型
"""

from datetime import datetime
from enum import Enum
from typing import List, Optional, Dict, Any

from pydantic import BaseModel, Field, field_validator, ConfigDict, model_serializer


class MCPStatus(int, Enum):
    """MCP工具接入状态枚举"""
    TESTING = 0  # 测试中
    ONLINE = 1  # 已上线
    DISCONTINUED = 2  # 已下线

    @classmethod
    def validate_status(cls, value):
        """验证并转换status值"""
        if isinstance(value, int):
            if value in [0, 1, 2]:
                return value
            else:
                raise ValueError(f"无效的状态值: {value}，必须是 0, 1, 2 中的一个")
        elif isinstance(value, str):
            try:
                int_value = int(value)
                if int_value in [0, 1, 2]:
                    return int_value
                else:
                    raise ValueError(f"无效的状态值: {value}，必须是 0, 1, 2 中的一个")
            except ValueError:
                raise ValueError(f"无效的状态值: {value}，必须是 0, 1, 2 中的一个")
        else:
            raise ValueError(f"状态值必须是整数，当前类型: {type(value)}")


class MCPAccessType(int, Enum):
    """MCP工具接入类型枚举"""
    API = 1  # API接入
    LOCAL_TOOL = 2  # 本地工具

    @classmethod
    def validate_access_type(cls, value):
        """验证并转换accessType值"""
        if isinstance(value, int):
            if value in [1, 2]:
                return value
            else:
                raise ValueError(f"无效的接入类型: {value}，必须是 1, 2 中的一个")
        elif isinstance(value, str):
            try:
                int_value = int(value)
                if int_value in [1, 2]:
                    return int_value
                else:
                    raise ValueError(f"无效的接入类型: {value}，必须是 1, 2 中的一个")
            except ValueError:
                raise ValueError(f"无效的接入类型: {value}，必须是 1, 2 中的一个")
        else:
            raise ValueError(f"接入类型必须是整数，当前类型: {type(value)}")


class AIWebMCPTools(BaseModel):
    """AI Web MCP工具实体类"""
    id: Optional[int] = Field(None, description="主键ID")
    mcp_name: str = Field(..., max_length=200, description="MCP工具名称")
    description: Optional[str] = Field(None, max_length=500, description="MCP工具描述")
    status: int = Field(default=0, description="接入状态（0=测试中,1=已上线,2=已下线）")
    access_type: int = Field(..., description="接入类型（1=API,2=本地工具）")
    doc_url: Optional[str] = Field(None, description="文档URL")
    json_schema: Optional[Dict[str, Any]] = Field(None, description="JSON配置内容")
    created_at: Optional[datetime] = Field(None, description="创建时间")
    updated_at: Optional[datetime] = Field(None, description="更新时间")

    model_config = ConfigDict(from_attributes=True)

    @model_serializer
    def serialize_model(self):
        """自定义序列化器"""
        data = self.__dict__.copy()
        if 'created_at' in data and data['created_at']:
            data['created_at'] = data['created_at'].isoformat()
        if 'updated_at' in data and data['updated_at']:
            data['updated_at'] = data['updated_at'].isoformat()
        return data

    @field_validator('id', mode='before')
    @classmethod
    def validate_id(cls, v):
        """验证ID"""
        if v is None:
            # 如果没有提供ID，返回None，让数据库自动生成
            return None
        if isinstance(v, str):
            try:
                return int(v)
            except ValueError:
                raise ValueError(f"无效的ID值: {v}，必须是整数")
        if isinstance(v, int):
            return v
        raise ValueError(f"ID必须是整数类型，当前类型: {type(v)}")

    @field_validator('status', mode='before')
    @classmethod
    def validate_status(cls, v):
        """验证status字段"""
        return MCPStatus.validate_status(v)

    @field_validator('access_type', mode='before')
    @classmethod
    def validate_access_type(cls, v):
        """验证access_type字段"""
        return MCPAccessType.validate_access_type(v)

    @field_validator('mcp_name')
    @classmethod
    def validate_mcp_name(cls, v):
        """验证MCP工具名称"""
        if not v or not v.strip():
            raise ValueError('MCP工具名称不能为空')
        if len(v.strip()) > 200:
            raise ValueError('MCP工具名称长度不能超过200个字符')
        return v.strip()

    def get_status_display(self) -> str:
        """获取状态显示文本"""
        status_map = {
            0: "测试中",
            1: "已上线",
            2: "已下线"
        }
        return status_map.get(self.status, "未知状态")

    def get_access_type_display(self) -> str:
        """获取接入类型显示文本"""
        type_map = {
            1: "API接入",
            2: "本地工具"
        }
        return type_map.get(self.access_type, "未知类型")

    def is_online(self) -> bool:
        """判断是否已上线"""
        return self.status == MCPStatus.ONLINE

    def is_testing(self) -> bool:
        """判断是否在测试中"""
        return self.status == MCPStatus.TESTING

    def is_discontinued(self) -> bool:
        """判断是否已下线"""
        return self.status == MCPStatus.DISCONTINUED


class AIWebMCPToolsCreate(BaseModel):
    """创建MCP工具请求模型"""
    id: Optional[int] = Field(None, description="主键ID（可选，不提供则数据库自动生成）")
    mcp_name: str = Field(..., max_length=200, description="MCP工具名称")
    description: Optional[str] = Field(None, max_length=500, description="MCP工具描述")
    status: int = Field(default=0, description="接入状态（0=测试中,1=已上线,2=已下线）")
    access_type: int = Field(..., description="接入类型（1=API,2=本地工具）")
    doc_url: Optional[str] = Field(None, max_length=500, description="文档URL")
    json_schema: Optional[Dict[str, Any]] = Field(None, description="JSON配置内容")

    @field_validator('id', mode='before')
    @classmethod
    def validate_id(cls, v):
        """验证ID"""
        if v is None:
            # 如果没有提供ID，返回None，让数据库自动生成
            return None
        if isinstance(v, str):
            try:
                return int(v)
            except ValueError:
                raise ValueError(f"无效的ID值: {v}，必须是整数")
        if isinstance(v, int):
            return v
        raise ValueError(f"ID必须是整数类型，当前类型: {type(v)}")

    @field_validator('status', mode='before')
    @classmethod
    def validate_status(cls, v):
        """验证status字段"""
        return MCPStatus.validate_status(v)

    @field_validator('access_type', mode='before')
    @classmethod
    def validate_access_type(cls, v):
        """验证access_type字段"""
        return MCPAccessType.validate_access_type(v)

    @field_validator('mcp_name')
    @classmethod
    def validate_mcp_name(cls, v):
        """验证MCP工具名称"""
        if not v or not v.strip():
            raise ValueError('MCP工具名称不能为空')
        if len(v.strip()) > 200:
            raise ValueError('MCP工具名称长度不能超过200个字符')
        return v.strip()


class AIWebMCPToolsUpdate(BaseModel):
    """更新MCP工具请求模型"""
    mcp_name: Optional[str] = Field(None, max_length=200, description="MCP工具名称")
    description: Optional[str] = Field(None, max_length=500, description="MCP工具描述")
    status: Optional[int] = Field(None, description="接入状态（0=测试中,1=已上线,2=已下线）")
    access_type: Optional[int] = Field(None, description="接入类型（1=API,2=本地工具）")
    doc_url: Optional[str] = Field(None, max_length=500, description="文档URL")
    json_schema: Optional[Dict[str, Any]] = Field(None, description="JSON配置内容")

    @field_validator('status', mode='before')
    @classmethod
    def validate_status(cls, v):
        """验证status字段"""
        if v is not None:
            return MCPStatus.validate_status(v)
        return v

    @field_validator('access_type', mode='before')
    @classmethod
    def validate_access_type(cls, v):
        """验证access_type字段"""
        if v is not None:
            return MCPAccessType.validate_access_type(v)
        return v

    @field_validator('mcp_name')
    @classmethod
    def validate_mcp_name(cls, v):
        """验证MCP工具名称"""
        if v is not None:
            if not v or not v.strip():
                raise ValueError('MCP工具名称不能为空')
            if len(v.strip()) > 200:
                raise ValueError('MCP工具名称长度不能超过200个字符')
            return v.strip()
        return v


class AIWebMCPToolsResponse(BaseModel):
    """MCP工具响应模型"""
    id: int
    mcp_name: str
    description: Optional[str]
    status: int
    access_type: int
    doc_url: Optional[str]
    json_schema: Optional[Dict[str, Any]]
    created_at: datetime
    updated_at: datetime

    # 额外的显示字段
    status_display: Optional[str] = None
    access_type_display: Optional[str] = None

    model_config = ConfigDict(from_attributes=True)

    @model_serializer
    def serialize_model(self):
        """自定义序列化器"""
        data = self.__dict__.copy()
        if 'created_at' in data and data['created_at']:
            data['created_at'] = data['created_at'].isoformat()
        if 'updated_at' in data and data['updated_at']:
            data['updated_at'] = data['updated_at'].isoformat()
        return data

    @field_validator('status_display', mode='before')
    @classmethod
    def set_status_display(cls, v, info):
        """设置状态显示文本"""
        if hasattr(info, 'data') and 'status' in info.data:
            status_map = {0: "测试中", 1: "已上线", 2: "已下线"}
            return status_map.get(info.data['status'], "未知状态")
        return v

    @field_validator('access_type_display', mode='before')
    @classmethod
    def set_access_type_display(cls, v, info):
        """设置接入类型显示文本"""
        if hasattr(info, 'data') and 'access_type' in info.data:
            type_map = {1: "API接入", 2: "本地工具"}
            return type_map.get(info.data['access_type'], "未知类型")
        return v


class AIWebMCPToolsQueryParams(BaseModel):
    """MCP工具查询参数"""
    mcp_name: Optional[str] = Field(None, description="MCP工具名称模糊查询")
    status: Optional[int] = Field(None, description="状态筛选")
    access_type: Optional[int] = Field(None, description="接入类型筛选")

    @field_validator('status', mode='before')
    @classmethod
    def validate_status(cls, v):
        """验证status字段"""
        if v is not None:
            return MCPStatus.validate_status(v)
        return v

    @field_validator('access_type', mode='before')
    @classmethod
    def validate_access_type(cls, v):
        """验证access_type字段"""
        if v is not None:
            return MCPAccessType.validate_access_type(v)
        return v


class AIWebMCPToolsListResponse(BaseModel):
    """MCP工具列表响应模型"""
    total: int = Field(..., description="总数量")
    items: List[AIWebMCPToolsResponse] = Field(..., description="MCP工具列表")


class AIWebMCPToolsStatusUpdate(BaseModel):
    """MCP工具状态更新模型"""
    status: int = Field(..., description="新状态")

    @field_validator('status', mode='before')
    @classmethod
    def validate_status(cls, v):
        """验证status字段"""
        return MCPStatus.validate_status(v)
